import { fabric } from 'fabric';

/**
 * 项目公共工具函数集合
 */

// 颜色处理工具
export const ColorUtils = {
    /**
     * 验证十六进制颜色格式
     * @param {string} color - 颜色字符串
     * @returns {boolean} 是否有效
     */
    isValidHexColor: (color) => {
        return /^#([0-9A-F]{3}){1,2}$/i.test(color);
    },

    /**
     * 将RGB颜色转换为十六进制
     * @param {number} r - 红色值(0-255)
     * @param {number} g - 绿色值(0-255)
     * @param {number} b - 蓝色值(0-255)
     * @returns {string} 十六进制颜色字符串
     */
    rgbToHex: (r, g, b) => {
        return `#${[r, g, b]
            .map((x) => {
                const hex = x.toString(16);
                return hex.length === 1 ? `0${hex}` : hex;
            })
            .join('')}`;
    }
};

// 画布工具
export const CanvasUtils = {
    /**
     * 导出画布为图片
     * @param {fabric.Canvas} canvas - fabric画布实例
     * @param {Object} options - 导出选项
     * @param {string} [options.format='png'] - 图片格式(png/jpeg)
     * @param {number} [options.quality=1] - 图片质量(0-1)
     * @param {number} [options.multiplier=2] - 导出倍率，值越大图片质量越高
     * @param {boolean} [options.enableRetinaScaling=true] - 是否启用视网膜缩放
     * @returns {Promise<string>} 图片数据URL
     */
    exportToImage: (canvas, options = {}) => {
        return new Promise((resolve, reject) => {
            if (!canvas) {
                reject(new Error('Canvas is required'));
                return;
            }

            try {
                const {
                    format = 'png',
                    quality = 1,
                    multiplier = 2,
                    enableRetinaScaling = true
                } = options;

                const dataURL = canvas.toDataURL({
                    format,
                    quality,
                    multiplier,
                    enableRetinaScaling
                });

                // 触发成功事件
                const successEvent = new CustomEvent('export-success');
                document.dispatchEvent(successEvent);

                resolve(dataURL);
            } catch (error) {
                // 触发失败事件
                const failEvent = new CustomEvent('export-fail');
                document.dispatchEvent(failEvent);

                reject(error);
            }
        });
    },

    /**
     * 初始化画布缩放功能
     * @param {fabric.Canvas} canvas - fabric画布实例
     * @param {Object} options - 缩放选项
     * @param {number} [options.minZoom=0.1] - 最小缩放倍率
     * @param {number} [options.maxZoom=10] - 最大缩放倍率
     * @param {number} [options.zoomStep=0.1] - 每次缩放的步长
     */
    initZoom: (canvas, options = {}) => {
        if (!canvas) return;

        const { minZoom = 0.1, maxZoom = 10, zoomStep = 0.1 } = options;

        // 存储当前缩放值
        canvas.zoomLevel = 1;

        // 设置缩放事件
        canvas.on('mouse:wheel', (opt) => {
            const delta = opt.e.deltaY;
            let zoom = canvas.getZoom();

            // 向下滚动 - 缩小
            if (delta > 0) {
                zoom -= zoomStep;
            }
            // 向上滚动 - 放大
            else {
                zoom += zoomStep;
            }

            // 限制缩放范围
            zoom = Math.min(Math.max(minZoom, zoom), maxZoom);

            // 计算缩放的中心点（鼠标位置）
            const point = {
                x: opt.e.offsetX,
                y: opt.e.offsetY
            };

            // 应用缩放
            canvas.zoomToPoint(point, zoom);
            canvas.zoomLevel = zoom;

            // 阻止页面滚动
            opt.e.preventDefault();
            opt.e.stopPropagation();
        });
    },

    /**
     * 重置画布缩放
     * @param {fabric.Canvas} canvas - fabric画布实例
     */
    resetZoom: (canvas) => {
        canvas.setViewportTransform([1, 0, 0, 1, 0, 0]);
        canvas.setZoom(1);
    },

    /**
     * 对画布应用网格背景
     * @param {fabric.Canvas} canvas - fabric画布实例
     * @param {Object} options - 网格选项
     * @param {number} [options.gridSize=20] - 网格大小
     * @param {string} [options.gridColor='#e0e0e0'] - 网格颜色
     * @param {number} [options.gridOpacity=0.5] - 网格透明度
     */
    // applyGrid: (canvas, options = {}) => {
    //   if (!canvas) return;

    //   const {
    //     gridSize = 20,
    //     gridColor = '#e0e0e0',
    //     gridOpacity = 0.5
    //   } = options;

    //   const width = canvas.getWidth();
    //   const height = canvas.getHeight();

    //   // 创建网格
    //   const gridLines = [];

    //   // 创建水平线
    //   for (let i = 0; i <= height / gridSize; i++) {
    //     const y = i * gridSize;
    //     const line = new fabric.Line([0, y, width, y], {
    //       stroke: gridColor,
    //       opacity: gridOpacity,
    //       selectable: false,
    //       evented: false,
    //       excludeFromExport: true
    //     });
    //     gridLines.push(line);
    //   }

    //   // 创建垂直线
    //   for (let i = 0; i <= width / gridSize; i++) {
    //     const x = i * gridSize;
    //     const line = new fabric.Line([x, 0, x, height], {
    //       stroke: gridColor,
    //       opacity: gridOpacity,
    //       selectable: false,
    //       evented: false,
    //       excludeFromExport: true
    //     });
    //     gridLines.push(line);
    //   }

    //   // 先清除现有网格
    //   canvas.getObjects().forEach(obj => {
    //     if (obj.isGrid) {
    //       canvas.remove(obj);
    //     }
    //   });

    //   // 添加网格标记
    //   gridLines.forEach(line => {
    //     line.isGrid = true;
    //     canvas.add(line);
    //   });

    //   // 将网格发送到底层
    //   gridLines.forEach(line => {
    //     canvas.sendToBack(line);
    //   });

    //   canvas.requestRenderAll();
    //   return gridLines;
    // },

    /**
     * 优化画布性能的函数
     * @param {fabric.Canvas} canvas - fabric画布实例
     */
    optimizePerformance: (canvas) => {
        if (!canvas) return;

        // 禁用对象控制
        canvas.getObjects().forEach((obj) => {
            // 暂时禁用控制点以提高性能
            obj._controlsVisibility = {
                bl: false,
                br: false,
                mb: false,
                ml: false,
                mr: false,
                mt: false,
                tl: false,
                tr: false,
                mtr: false
            };
        });

        // 使用requestAnimationFrame优化多次渲染
        if (canvas._renderDebounced) return;

        canvas._renderDebounced = true;
        requestAnimationFrame(() => {
            canvas.requestRenderAll();
            canvas._renderDebounced = false;
        });
    },

    /**
     * 获取优化后的防抖渲染函数
     * @param {fabric.Canvas} canvas - fabric画布实例
     * @param {number} [wait=100] - 防抖时间(ms)
     * @returns {Function} 防抖处理后的渲染函数
     */
    getThrottledRender: (canvas, wait = 100) => {
        if (!canvas) return () => {};

        let timeout;
        let lastRenderTime = 0;

        return () => {
            const now = Date.now();

            // 如果距离上次渲染时间不足wait毫秒，则设置延迟渲染
            if (now - lastRenderTime < wait) {
                clearTimeout(timeout);
                timeout = setTimeout(() => {
                    lastRenderTime = Date.now();
                    canvas.requestRenderAll();
                }, wait);
                return;
            }

            // 否则立即渲染
            lastRenderTime = now;
            canvas.requestRenderAll();
        };
    }
};

// 对象操作工具
export const ObjectUtils = {
    /**
     * 将对象置顶
     * @param {fabric.Object} obj - fabric对象
     * @param {fabric.Canvas} canvas - fabric画布
     */
    bringToFront: (obj, canvas) => {
        canvas.bringToFront(obj);
        canvas.requestRenderAll();
    },

    /**
     * 将对象置底
     * @param {fabric.Object} obj - fabric对象
     * @param {fabric.Canvas} canvas - fabric画布
     */
    sendToBack: (obj, canvas) => {
        canvas.sendToBack(obj);
        canvas.requestRenderAll();
    },

    /**
     * 删除选中对象
     * @param {fabric.Canvas} canvas - fabric画布
     */
    deleteSelected: (canvas) => {
        if (!canvas || !canvas.getActiveObject) return;
        const activeObject = canvas.getActiveObject();
        if (activeObject) {
            canvas.remove(activeObject);
            canvas.discardActiveObject();
            canvas.requestRenderAll();
        }
    }
};

// 文本处理工具
export const TextUtils = {
    /**
     * 应用文本样式
     * @param {fabric.Text} textObject - fabric文本对象
     * @param {Object} styles - 样式对象
     * @param {string} [styles.fontFamily] - 字体
     * @param {number} [styles.fontSize] - 字号
     * @param {boolean} [styles.bold] - 是否加粗
     * @param {boolean} [styles.italic] - 是否斜体
     * @param {boolean} [styles.underline] - 是否有下划线
     * @param {boolean} [styles.linethrough] - 是否有删除线
     * @param {string} [styles.color] - 文本颜色
     */
    applyTextStyles: (textObject, styles) => {
        if (!textObject || !textObject.set) return;

        textObject.set({
            fontFamily: styles.fontFamily || textObject.fontFamily,
            fontSize: styles.fontSize || textObject.fontSize,
            fontWeight: styles.bold ? 'bold' : 'normal',
            fontStyle: styles.italic ? 'italic' : 'normal',
            underline: styles.underline || false,
            linethrough: styles.linethrough || false,
            fill: styles.color || textObject.fill
        });

        textObject.dirty = true;
    },

    /**
     * 创建文本属性处理函数
     * @param {Function} setState - 设置组件状态的函数
     * @param {Function} [onChange] - 属性变化回调函数
     * @returns {Object} 文本属性处理函数集合
     */
    createTextHandlers: (setState, onChange) => {
        return {
            handleFontFamilyChange: (value) => {
                setState((prev) => ({ ...prev, fontFamily: value }));
                onChange?.('fontFamily', value);
            },
            handleFontSizeChange: (value) => {
                setState((prev) => ({ ...prev, fontSize: value }));
                onChange?.('fontSize', value);
            },
            handleTextColorChange: (color) => {
                setState((prev) => ({ ...prev, color }));
                onChange?.('fill', color);
            },
            handleBoldToggle: (current) => {
                const newValue = !current;
                setState((prev) => ({ ...prev, bold: newValue }));
                onChange?.('fontWeight', newValue ? 'bold' : 'normal');
            },
            handleItalicToggle: (current) => {
                const newValue = !current;
                setState((prev) => ({ ...prev, italic: newValue }));
                onChange?.('fontStyle', newValue ? 'italic' : 'normal');
            },
            handleUnderlineToggle: (current) => {
                const newValue = !current;
                setState((prev) => ({ ...prev, underline: newValue }));
                onChange?.('underline', newValue);
            },
            handleLinethroughToggle: (current) => {
                const newValue = !current;
                setState((prev) => ({ ...prev, linethrough: newValue }));
                onChange?.('linethrough', newValue);
            }
        };
    },

    /**
     * 获取默认字体列表
     * @returns {Array} 字体列表
     */
    getDefaultFonts: () => {
        return ['Arial', 'Times New Roman', 'Courier New', 'Georgia', 'Verdana', 'Helvetica'];
    }
};

// 文件处理工具
export const FileUtils = {
    /**
     * 导出画布为图片文件
     * @param {fabric.Canvas} canvas - fabric画布
     * @param {string} [fileName='canvas'] - 文件名
     * @param {string} [format='png'] - 图片格式(png/jpeg)
     * @param {number} [quality=1] - 图片质量(0-1)
     */
    exportCanvasToImage: async (canvas, fileName = 'canvas', format = 'png', quality = 1) => {
        if (!canvas || !canvas.toDataURL) return;

        const dataURL = await CanvasUtils.exportToImage(canvas, { format, quality });
        const link = document.createElement('a');
        link.download = `${fileName}.${format}`;
        link.href = dataURL;
        link.click();
    },

    /**
     * 读取图片文件为DataURL
     * @param {File} file - 图片文件
     * @returns {Promise<string>} DataURL
     */
    readImageFile: (file) => {
        return new Promise((resolve) => {
            const reader = new FileReader();
            reader.onload = (e) => resolve(e.target.result);
            reader.readAsDataURL(file);
        });
    }
};

// 状态管理工具
export const StateUtils = {
    /**
     * 函数节流
     * @param {Function} func - 需要节流的函数
     * @param {number} delay - 延迟时间(毫秒)
     * @returns {Function} 节流后的函数
     */
    debounce: (func, delay) => {
        let timeoutId;
        return (...args) => {
            clearTimeout(timeoutId);
            timeoutId = setTimeout(() => func.apply(this, args), delay);
        };
    },

    /**
     * 创建历史状态管理器
     * @returns {Object} 状态管理对象
     */
    createHistoryManager: () => {
        const states = [];
        let currentIndex = -1;

        return {
            addState: (state) => {
                states.splice(currentIndex + 1);
                states.push(JSON.parse(JSON.stringify(state)));
                currentIndex = states.length - 1;
            },
            getCurrentState: () => states[currentIndex],
            canUndo: () => currentIndex > 0,
            canRedo: () => currentIndex < states.length - 1,
            undo: () => {
                if (this.canUndo()) currentIndex--;
                return states[currentIndex];
            },
            redo: () => {
                if (this.canRedo()) currentIndex++;
                return states[currentIndex];
            },
            clear: () => {
                states.length = 0;
                currentIndex = -1;
            }
        };
    }
};
